package gxprod.androidai;

import java.util.Arrays;
import java.util.List;

public enum Unit {	

	// -------------------- //
	// ------ Length ------ //
	// -------------------- //

	Millimeter	(1000, 					UVs.LENGTH | UVs.METRIC, "millimeter", "millimeters", "mm"),
	Centameter	(100,					UVs.LENGTH | UVs.METRIC, "centameter", "centameters", "cm"),
	Decimeter	(10, 					UVs.LENGTH | UVs.METRIC, "decigram", "decigrams", "dg"),
	Meter		(1, 					UVs.LENGTH | UVs.METRIC, "meter", "meters", "m"),
	___meter	(0.1,					UVs.LENGTH | UVs.METRIC, "___meter", "___meters", "_m"),
	Kilometer	(0.001, 				UVs.LENGTH | UVs.METRIC, "kilometer", "kilometers", "km"),

	Inch		(39.3700787401575,		UVs.LENGTH | UVs.IMPERIAL, "inch", "inches", "in", "\""),
	Foot		(3.28083989501312,		UVs.LENGTH | UVs.IMPERIAL, "feet", "ft", "foot", "\'"),
	Yard		(1.09361329833771,		UVs.LENGTH | UVs.IMPERIAL, "yard", "yards", "yd", "yd"),
	Mile		(6.21371192237334e-4,	UVs.LENGTH | UVs.IMPERIAL, "mile", "miles", "mi"),

	Parsect		(3.24077829926234e-17, 	UVs.LENGTH, "parsect", "parsetcs"),
	AustornomicalUnit(6.68458507186356e-12, UVs.LENGTH, "austronomical unit", "austronomical unit", "au", "aus"),
	LightYear	(1.05702341053618e-16, 	UVs.LENGTH, "light year", "lightyears"),


	// --------------------- //
	// ------ Volume ------- //
	// --------------------- //

	Milliliter	(1000.0, 		UVs.VOLUME | UVs.METRIC, "ml", ",milliliter", "millitiers"),
	Liter		(1.0, 			UVs.VOLUME | UVs.METRIC, "l", "liter", "liters"),
	Kiloliter	(0.001, 		UVs.VOLUME | UVs.METRIC, "kiloliter", "kiloliters", "kl"),

	Ounce_		(33.8140227, 	UVs.VOLUME | UVs.IMPERIAL, "fluid ounce", "fluid ounces"),
	Cup			(4.22675284, 	UVs.VOLUME | UVs.IMPERIAL, "cup", "cups"),
	Pint		(2.11337642, 	UVs.VOLUME | UVs.IMPERIAL, "pint", "pints"),
	Quart		(1.05668821, 	UVs.VOLUME | UVs.IMPERIAL, "quarts", "quart", "q"),
	Gallon		(0.264172052, 	UVs.VOLUME | UVs.IMPERIAL, "gallon", "gallons"),

	// --------------------- //
	// ------ Weight ------- //
	// --------------------- //

	Milligram	(1000, 					UVs.WEIGHT | UVs.METRIC, "milligram", "milligrams", "mg"),
	Gram		(1.0, 					UVs.WEIGHT | UVs.METRIC, "gram", "grams", "g"),
	Kilogram	(0.001, 				UVs.WEIGHT | UVs.METRIC, "kilogram", "kilograms", "kg"),
	MetricTon	(0.000001, 				UVs.WEIGHT | UVs.METRIC, "metric ton", "metric tons", "mt"),

	Ounce		(0.0352739619495804,  	UVs.WEIGHT | UVs.IMPERIAL, "ounce", "ounces", "oz"),
	Pound		(0.00220462262184878, 	UVs.WEIGHT | UVs.IMPERIAL, "pound", "pounds", "lb", "lbs"),
	Ton			(1.10231131092439e-6, 	UVs.WEIGHT | UVs.IMPERIAL, "ton", "tons", "short ton", "short tons", "t"),	


	Newton		(0.00980665, 			UVs.WEIGHT, "newton", "newtons", "n"),

	// --------------------- //
	// -------- Area ------- //
	// --------------------- //

	SqMilliMeter(1000000,			UVs.AREA, "square millimeter", "square millimeters", "mm^2", "mm²"),
	SqCentaMeter(10000,				UVs.AREA, "square centameter", "square centameters", "cm^2", "cm²"),
	SqDecaMeter	(100,				UVs.AREA, "square decameter", "square decameter", "dm^2", "dm²"),
	SqMeter		(1, 				UVs.AREA, "square meter", "square meters", "m^2", "m²"),	
	SqKiloMeter (0.0000001,			UVs.AREA, "square kilometer", "square kilometer", "km^2", "km²"),

	SqInch		(1550.0031000062,	UVs.AREA, "square inch", "square inches", "in^2", "in²"),	
	SqFoot		(10.7639104167097,	UVs.AREA, "square foot", "square feet", "ft^2", "ft²"),
	SqYard		(1.19599004630108,	UVs.AREA, "square yard", "square yards", "yd^2","yd²"),

	// --------------------- //
	// -------- Angle ------ //
	// --------------------- //

	Degrees		(57.2957795130823,	UVs.ANGLE, "degree", "degrees", "°"),
	Radians		(1,					UVs.ANGLE, "radian", "radians", "r"),

	// --------------------- //
	// -------- Time ------- //
	// --------------------- //

	Millinium	(1/60/60/24/365000,	UVs.TIME, "millinium", "milliniums"),
	Century		(1/60/60/24/36500,	UVs.TIME, "century", "centuries"),
	Decade		(1/60/60/24/3650,	UVs.TIME, "decade", "decades"),
	Year		(1/60/60/24/365,	UVs.TIME, "year", "years"),
	Week		(1/60/60/24/7,		UVs.TIME, "week", "weeks"),
	Day			(1/60/60/24,		UVs.TIME, "day", "days"),
	Hour		(1/60/60,			UVs.TIME, "hour", "hours", "hr"),
	Minuet		(1/ 60,				UVs.TIME, "minuet", "minuets"),		
	Second		(1,					UVs.TIME, "second", "seconds", "sec", "s"),
	Millisecond	(1000,				UVs.TIME, "millisecond", "milliseconds", "ms"),
	Microsecond	(1000000,			UVs.TIME, "microsecond", "microseconds"),	
	Nanosecond	(1000000000,		UVs.TIME, "nanosecond", "nanoseconds"),

	// --------------------- //
	// -------- Speed ------ //
	// --------------------- //
	
	
	
	// --------------------- //
	// ----- Temputure ----- //
	// --------------------- //

	Farenhite	(1.8,	255.37222222222222,	UVs.TEMPUTURE | UVs.IMPERIAL, 	"degree farenhite", "degrees farenhite", "°f", "*f"),
	Celcius		(1, 	273.15, 			UVs.TEMPUTURE | UVs.METRIC,		"degree celcius", "degrees celcius", "degree centigrade", "degrees centigrade", "celcius", "centigrade", "°c", "*c", "c"),
	Kelvin		(1,		0,					UVs.TEMPUTURE | UVs.METRIC,		"degree kelvin", "degrees kelvin", "kelvin", "*k", "°k", "k"),
	Rankine		(1.8,	491.67777777777777,	UVs.TEMPUTURE | UVs.IMPERIAL,	"degree rankine", "degrees rankine", "°r", "*r"),	

	// --------------------- //
	// -------- Misk ------- //
	// --------------------- //

	Unknown(0, 0);

	
	public double Ratio;
	public double Offset;
	public int Flags;
	public List<String> Aliases;

	Unit(double ratio, int flags) { this(ratio, flags, new String[]{}); }
	Unit(double ratio, int flags, String ...aliases) {
		Ratio = ratio;
		Flags = flags;
		Aliases = Arrays.asList(aliases);
		Offset = 0;
	}

	Unit(double ratio, double offset, int flags, String ...aliases) {
		Ratio = ratio;
		Flags = flags;
		Aliases = Arrays.asList(aliases);
		Offset = offset;
	}

	public class UVs {

		public static final int NONE				= 0x00000000;

		public static final int FILTER_CONV			= 0xF0000000;
		public static final int FILTER_TYPE			= 0x00000FFF;

		public static final int METRIC				= 0x10000000;
		public static final int IMPERIAL			= 0x20000000;

		public static final int LENGTH				= 0x00000001;
		public static final int VOLUME				= 0x00000002;
		public static final int WEIGHT				= 0x00000004;
		public static final int TEMPUTURE			= 0x00000008;
		public static final int AREA 				= 0x0000000F;
		public static final int ANGLE				= 0x00000010;
		public static final int TIME 				= 0x00000020;
		public static final int SPEED 				= 0x00000040;
	}

	public boolean isOfSameType(Unit u) {
		return (Flags & u.Flags & UVs.FILTER_TYPE) > 0;
	}

	public static Unit find(String name) {
		name = name.toLowerCase();
		for (Unit u : Unit.values()) {
			if (u.Aliases.contains(name)) {
				return u;
			}
		}
		return null;
	}

	public double convert(double val, Unit target) {
		val -= Offset;
		val *= Ratio / target.Ratio;
		return val + target.Offset;
	}
}